#include <stdio.h>
#include <stdlib.h>     //exit()
#include <string>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <wsim/websocket_common.h>
#include <map>
#include <jsoncpp/json/json.h>/* jsoncpp -ljsoncpp*/
#include "wsim.h"

#include <iostream>
#include "websocket_handler.h"

using namespace std;


websocket_handler::~websocket_handler()
{
}
websocket_handler::websocket_handler(websocket_handler* src)
{
    fd=src->getFd();
    uuid=src->getUUID();
    nickname=src->getNickname();
    mood=src->getMood();
    bReg=src->getReg();
    organ=src->getOrgan();
    group=src->getGroup();
}
websocket_handler::websocket_handler(int f)
{
	fd=f;
	char guid[37];
	random_uuid(guid);
	uuid=guid;
    bReg=false;
    nickname="";
    mood="";
    organ="";
    group="";
}
int websocket_handler::getFd()
{
    return fd;
}
/********************************************
*改昵称
*****************************************/
void websocket_handler::reNickname(string nick)
{
	nickname=nick;
}
/*********************************************
*比较昵称
*********************************************/
int websocket_handler::cmpNickname(string nick)
{
	return nickname.compare(nick);
}
/*******************************************
 *  匹配fd
 * *****************************************/
int websocket_handler::cmpFd(int f)
{
    return fd-f;
}

/***********************************************
 * 匹配UUID
 * *******************************************/
int websocket_handler::cmpUUID(string id)
{
        return uuid.compare(id);
}
string websocket_handler::getNickname()
{
	return nickname;
}
string websocket_handler::getUUID()
{
	return uuid;
}
string websocket_handler::getMood()
{
    return mood;
}
void websocket_handler::reMood(string s)
{
    mood=s;
}
bool websocket_handler::getReg()
{
    return bReg;
}
void websocket_handler::reged()
{
    bReg=true;
}
string websocket_handler::getGroup()
{
    return group;
}
string websocket_handler::getOrgan()
{
    return organ;
}
void websocket_handler::reGroup(string val)
{
    group=val;
}
void websocket_handler::reOrgan(string val)
{
    organ=val;
}

typedef std::map<int ,websocket_handler*> HANDLER_MAP;
HANDLER_MAP client_map;

/*****************************************
 * 添加客户
 * *************************************/
void addClient(int fd)
{
    pthread_mutex_lock(&mutex_client_map_lock);
    HANDLER_MAP::iterator client_it=client_map.find(fd);
		if(client_it==client_map.end())
		{
			client_map[fd]=new websocket_handler(fd);
		}
    pthread_mutex_unlock(&mutex_client_map_lock);
}
/****************************
 * 删除客户
 * *************************/
void deleteClient(int fd)
{
    pthread_mutex_lock(&mutex_client_map_lock);
        HANDLER_MAP::iterator it=client_map.find(fd);
	if(it!=client_map.end())
	{
            //webSocket_send(fd,"quit",4,false,WDT_DISCONN);
		delete client_map[fd];			
		client_map.erase(it);

	}
    pthread_mutex_unlock(&mutex_client_map_lock);
}
/****************************
 * 设置客户昵称
 * *************************/
void setClientNickname(int fd ,string nickname,bool b)
{
    pthread_mutex_lock(&mutex_client_map_lock);
    HANDLER_MAP::iterator it=client_map.find(fd);
    if(it!=client_map.end())
    {
        ((websocket_handler*)client_map[fd])->reNickname(nickname);
        if(b)
        ((websocket_handler*)client_map[fd])->reged();
    }
     pthread_mutex_unlock(&mutex_client_map_lock);
}
/****************************
 * 设置客户心情
 * *************************/
void setClientMood(int fd ,string mood)
{
    pthread_mutex_lock(&mutex_client_map_lock);
    HANDLER_MAP::iterator it=client_map.find(fd);
    if(it!=client_map.end())
    {
        ((websocket_handler*)client_map[fd])->reMood(mood);
    }
     pthread_mutex_unlock(&mutex_client_map_lock);
}
/*****************************
 * 设置客户所属机构
 *************************/
void setClientOrgan(int fd ,string val)
{
    pthread_mutex_lock(&mutex_client_map_lock);
    HANDLER_MAP::iterator it=client_map.find(fd);
    if(it!=client_map.end())
    {
        ((websocket_handler*)client_map[fd])->reOrgan(val);
    }
     pthread_mutex_unlock(&mutex_client_map_lock);
}
/*********************************************
 * 设置客户所属兴趣组
 * **********************************************/
void setClientGroup(int fd ,string val)
{
    pthread_mutex_lock(&mutex_client_map_lock);
    HANDLER_MAP::iterator it=client_map.find(fd);
    if(it!=client_map.end())
    {
        ((websocket_handler*)client_map[fd])->reGroup(val);
    }
     pthread_mutex_unlock(&mutex_client_map_lock);
}
/******************************
 * 获取客户信息
 * *****************************/
websocket_handler* getClientValue(int fd)
{
    websocket_handler* info=NULL;
    pthread_mutex_lock(&mutex_client_map_lock);
    HANDLER_MAP::iterator it=client_map.find(fd);
            if(it!=client_map.end())
            {
                info=new websocket_handler(client_map[fd]);                
            }
    pthread_mutex_unlock(&mutex_client_map_lock);
    return info;
}
/******************************
 * 客户是否存在
 * *********************/
bool isClient(int fd)
{
    bool b=false;
    pthread_mutex_lock(&mutex_client_map_lock);
    HANDLER_MAP::iterator it=client_map.find(fd);
            if(it!=client_map.end())
            b= true;
            else b=false;

    pthread_mutex_unlock(&mutex_client_map_lock);
    return b;
}
/******************************
 * 客户是否存在
 * *********************/
int isNickname(string nickname)
{
    int fd=0;
    pthread_mutex_lock(&mutex_client_map_lock);
    for(HANDLER_MAP::iterator it=client_map.begin();it!=client_map.end();it++)
    {
        websocket_handler *handler=(websocket_handler*)it->second;
        if(handler->cmpNickname(nickname)==0)
        {
            fd=it->first;
            break;
        }
    }
    pthread_mutex_unlock(&mutex_client_map_lock);
    return fd;
}
/*************************************************
 * 发数据到非本客户的所有其它客户
 * **********************************************/
void toNotInClients(int fd,char* data,int size,WebsocketData_Type type)
{
    int ret=-1;
    pthread_mutex_lock(&mutex_client_map_lock);
    for(HANDLER_MAP::iterator it=client_map.begin();it!=client_map.end();it++)
        {
                if(fd!=it->first)
                    //if(((websocket_handler*)it->second)->getReg())//已注册
                        ret=webSocket_send(it->first,data,size,false,type);
        }
    pthread_mutex_unlock(&mutex_client_map_lock);

}
/************************************************
 * 导出数据
 * 
 * ********************************************/
Json::Value clientMapToArray()
{
    Json::Value arrayUser;
    pthread_mutex_lock(&mutex_client_map_lock);
    for(HANDLER_MAP::iterator it=client_map.begin();it!=client_map.end();it++)
    {
        websocket_handler *handler=(websocket_handler*)it->second;
        string nickname=handler->getNickname();

        Json::Value item;
        item["fd"]=it->first;
        item["uuid"]=handler->getUUID();
        item["nickname"]=nickname;
        item["mood"]=handler->getMood();
        item["group"]=handler->getGroup();
        item["organ"]=handler->getOrgan();   
        item["breg"]=handler->getReg();     
        arrayUser.append(item);
        
    }
    pthread_mutex_unlock(&mutex_client_map_lock);
    return arrayUser;
}
/***********************************
 * 导出未注册数据
 * *************************************/
Json::Value clientMapNoRegToArray()
{
    Json::Value arrayUser;
    pthread_mutex_lock(&mutex_client_map_lock);
    for(HANDLER_MAP::iterator it=client_map.begin();it!=client_map.end();it++)
    {
        websocket_handler *handler=(websocket_handler*)it->second;
        string nickname=handler->getNickname();
        if(!handler->getReg())
        {
            Json::Value item;
            item["fd"]=it->first;
            item["uuid"]=handler->getUUID();
            item["nickname"]=nickname;
            item["mood"]=handler->getMood();
            item["group"]=handler->getGroup();
            item["organ"]=handler->getOrgan();
            item["breg"]=handler->getReg(); 
            arrayUser.append(item);
        }
       
    }
    pthread_mutex_unlock(&mutex_client_map_lock);
    return arrayUser;
}
/***********************************
 * 导出注册数据
 * *************************************/
Json::Value clientMapRegToArray()
{
    Json::Value arrayUser;
    pthread_mutex_lock(&mutex_client_map_lock);
    for(HANDLER_MAP::iterator it=client_map.begin();it!=client_map.end();it++)
    {
        websocket_handler *handler=(websocket_handler*)it->second;
        string nickname=handler->getNickname();
        if(handler->getReg())
        {
            Json::Value item;
            item["fd"]=it->first;
            item["uuid"]=handler->getUUID();
            item["nickname"]=nickname;
            item["mood"]=handler->getMood();
            item["group"]=handler->getGroup();
            item["organ"]=handler->getOrgan();
            item["breg"]=handler->getReg(); 
            arrayUser.append(item);
        }
       
    }
    pthread_mutex_unlock(&mutex_client_map_lock);
    return arrayUser;
}
/*************************************************
 * 同一机构客户
 * ************************************************/
Json::Value clientMapOrganToArray(string organ)
{
    Json::Value arrayUser;
    pthread_mutex_lock(&mutex_client_map_lock);
    for(HANDLER_MAP::iterator it=client_map.begin();it!=client_map.end();it++)
    {
        websocket_handler *handler=(websocket_handler*)it->second;
        string nickname=handler->getNickname();
        if(handler->getReg() && (organ.compare(handler->getOrgan())==0) && (organ.length()>0 ))
        {
        Json::Value item;
        item["fd"]=it->first;
        item["uuid"]=handler->getUUID();
        item["nickname"]=nickname;
        item["mood"]=handler->getMood();
        item["group"]=handler->getGroup();
        item["organ"]=handler->getOrgan();
        item["breg"]=handler->getReg(); 
        arrayUser.append(item);
        }
    }
    pthread_mutex_unlock(&mutex_client_map_lock);
    return arrayUser;
}
/*******************************************
 * 同组客户
 * ****************************************/
Json::Value clientMapGroupToArray(string group)
{
    Json::Value arrayUser;
    pthread_mutex_lock(&mutex_client_map_lock);
    for(HANDLER_MAP::iterator it=client_map.begin();it!=client_map.end();it++)
    {
        websocket_handler *handler=(websocket_handler*)it->second;
        string nickname=handler->getNickname();
        if(handler->getReg() && group.compare(handler->getGroup())==0 && group.length()>0)
        {
        Json::Value item;
        item["fd"]=it->first;
        item["uuid"]=handler->getUUID();
        item["nickname"]=nickname;
        item["mood"]=handler->getMood();
        item["group"]=handler->getGroup();
        item["organ"]=handler->getOrgan();
        item["breg"]=handler->getReg(); 
        arrayUser.append(item);
        }
    }
    pthread_mutex_unlock(&mutex_client_map_lock);
    return arrayUser;
}